package com.hxl.tech.gateway.auth.controller;

import cn.hutool.core.lang.Assert;
import com.hxl.tech.gateway.auth.annotate.ApiPrivilege;
import com.hxl.tech.gateway.auth.dto.Response;
import com.hxl.tech.gateway.auth.dto.user.*;
import com.hxl.tech.gateway.auth.dto.user.req.ApplicationOauthLoginReqDTO;
import com.hxl.tech.gateway.auth.exception.AuthException;
import com.hxl.tech.gateway.auth.model.User;
import com.hxl.tech.gateway.auth.oauth.OAuthUser;
import com.hxl.tech.gateway.auth.service.SmsService;
import com.hxl.tech.gateway.auth.service.UserService;
import com.hxl.tech.gateway.auth.util.CopyUtil;
import com.hxl.tech.gateway.auth.util.JwtUtil;
import com.hxl.tech.gateway.common.constant.AppConstant;
import com.hxl.tech.gateway.common.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.TimeUnit;

/**
 * 用户 Controller 
 * @author soliddq
 * @date 2023-10-10
 */
@Api(value = "用户管理", tags = "用户管理")
@RestController
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;
    private final SmsService smsService;

    @PostMapping("gateway.auth.user.register")
    @ApiOperation(value = "注册新用户", response = UserDTO.class)
    public Response saveRegister(@RequestBody @Validated UserSaveRegisterDTO registerDTO) {

        smsService.verify(registerDTO.getPhone(), registerDTO.getSmsCode());
        return Response.createSuccess(CopyUtil.to(userService.saveRegister(CopyUtil.to(registerDTO, User.class)), User.class));
    }

    @PostMapping("gateway.auth.user.login")
    @ApiOperation(value = "用户登录", response = UserDTO.class)
    public Response loginUserByPhone(@RequestBody @Validated UserLoginDTO loginDTO) {

        User user = userService.readByPhone(loginDTO.getPhone());
        String password = DigestUtils.md5Hex(user.getUserId() + loginDTO.getPassword());
        Assert.notNull(user, () -> new AuthException("账号不存在或密码错误"));
        Assert.equals(password, user.getPassword(), () -> new AuthException("账号不存在或密码错误"));

        String token = JwtUtil.sign(user, loginDTO.getPassword());
        String redisKey = AppConstant.REDIS_USER_TOKEN +token;
        RedisUtil.set(redisKey, token, 1, TimeUnit.DAYS);
        return Response.createSuccess(token);
    }

    @ApiPrivilege(needRole = AppConstant.ROLE_ADMIN)
    @PostMapping("gateway.auth.user.page")
    @ApiOperation(value = "分页查询用户", response = UserDTO.class, responseContainer = "List")
    public Response page(@RequestBody @Validated UserFindDTO findDTO) {

        return Response.createSuccess(CopyUtil.toPage(userService.page(findDTO), UserDTO.class));
    }

    @ApiPrivilege()
    @PostMapping("gateway.auth.user.read")
    @ApiOperation(value = "读取用户", response = UserDTO.class)
    public Response page(@RequestBody @Validated UserReadDTO readDTO) {

        return Response.createSuccess(CopyUtil.to(userService.read(readDTO.getUserId()), UserDTO.class));
    }

    @ApiPrivilege(needRole = AppConstant.ROLE_ADMIN)
    @PostMapping("gateway.auth.user.save")
    @ApiOperation(value = "新增用户", response = UserDTO.class)
    public Response page(@RequestBody @Validated UserSaveDTO saveDTO) {

        return Response.createSuccess(CopyUtil.to(userService.save(CopyUtil.to(saveDTO, User.class)), User.class));
    }

    @ApiPrivilege()
    @PostMapping("gateway.auth.user.update")
    @ApiOperation(value = "更新用户", response = UserDTO.class)
    public Response update(@RequestBody @Validated UserUpdateDTO updateDTO) {

        return Response.createSuccess(CopyUtil.to(userService.update(CopyUtil.to(updateDTO, User.class)), User.class));
    }

    @ApiPrivilege(needRole = AppConstant.ROLE_ADMIN)
    @PostMapping("gateway.auth.user.state.update")
    @ApiOperation(value = "启用或禁用用户", response = UserDTO.class)
    public Response updateState(@RequestBody @Validated UserStateUpdateDTO stateUpdateDTO) {

        return Response.createSuccess(CopyUtil.to(userService.updateState(stateUpdateDTO), User.class));
    }

    @PostMapping("gateway.auth.merchant.app.login")
    @ApiOperation(value = "商户登录（用于oauth2校验）", response = OAuthUser.class)
    public Response<OAuthUser> login(@RequestBody @Validated ApplicationOauthLoginReqDTO reqDTO) {
        return Response.createSuccess(userService.loginCheck(reqDTO));
    }

}
